package lang;

import util.Timer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author yuqi<307530884@qq.com> <2017/3/27>
 * @version 1.0
 * @since 1.0
 */
public class StringAppend {
    private String a = "a";
    private String b = "b";
    private String c = "c";
    private String d = "d";
    private String e = "e";

    private final String fa = "a";
    private final String fb = "b";
    private final String fc = "c";
    private final String fd = "d";
    private final String fe = "e";

    private final int loop = 1000;

    private int index = 3;

    public void strAddTest() {
        Method[] methods = getClass().getDeclaredMethods();

        List<SortableMethodEntity> methodList = new ArrayList<SortableMethodEntity>();
        for (Method method : methods) {
            Test testAnnotation = method.getAnnotation(Test.class);
            if (testAnnotation != null) {
                int sort = testAnnotation.sort();
                SortableMethodEntity sortableMethodEntity = new SortableMethodEntity(method, sort);
                methodList.add(sortableMethodEntity);
            }
        }

        Collections.sort(methodList);
        System.out.println(methodList);

        for (SortableMethodEntity sortableMethodEntity : methodList) {
            try {
                Method method = sortableMethodEntity.getMethod();
                String methodName = method.getName();
                method.invoke(this);//第一次加载进内存，加快执行速度

                Timer.begin();
                for (int i = 0; i < loop; i++) {
                    method.invoke(this);
                }
                Timer.end(methodName);
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            } catch (InvocationTargetException e1) {
                e1.printStackTrace();
            }
        }

    }

    @Test(sort = 0)
    private void strAdd() {
        String result = a + b + c + d + e;
    }

    @Test(sort = 1)
    private void strBuilderAppend() {
        String result = new StringBuilder(a).append(b).append(c).append(d).append(e).toString();
    }

    @Test(sort = 2)
    private void strBufferAppend() {
        String result = new StringBuffer(a).append(b).append(c).append(d).append(e).toString();
    }

    @Test(sort = 10)
    private void strAddFinal() {
        String result = fa + fb + fc + fd + fe;
    }

    @Test(sort = 11)
    private void strBuilderAppendFinal() {
        String result = new StringBuilder(fa).append(fb).append(fc).append(fd).append(fe).toString();
    }

    @Test(sort = 12)
    private void strBufferAppendFinal() {
        String result = new StringBuffer(fa).append(fb).append(fc).append(fd).append(fe).toString();
    }

    @Test(sort = 20)
    private void strAddIf() {
        String result = a + b;

        //模拟多个if
        for(int i = 0 ; i < loop/10 ; i++){
            if(index == 3){
                result = result + c;
            }
        }

        result = result + d + e;
    }

    @Test(sort = 21)
    private void strBuilderAppendIf() {
        StringBuilder sb = new StringBuilder(a).append(b);

        for(int i = 0 ; i < loop/10 ; i++) {
            if (index == 3) {
                sb.append(c);
            }
        }

        sb.append(d).append(e);
        String result = sb.toString();
    }

    @Test(sort = 22)
    private void strBufferAppendIf() {
        StringBuffer sb = new StringBuffer(a).append(b);

        for(int i = 0 ; i < loop/10 ; i++) {
            if (index == 3) {
                sb.append(c);
            }
        }

        sb.append(d).append(e);
        String result = sb.toString();
    }

    @Test(sort = 30)
    private void strAddFinalIf() {
        String result = fa + fb;

        //模拟多个if
        for(int i = 0 ; i < loop/10 ; i++){
            if(index == 3){
                result = result + fc;
            }
        }

        result = result + fd + fe;
    }

    @Test(sort = 31)
    private void strBuilderAppendFinalIf() {
        StringBuilder sb = new StringBuilder(fa).append(fb);

        for(int i = 0 ; i < loop/10 ; i++) {
            if (index == 3) {
                sb.append(fc);
            }
        }

        sb.append(fd).append(fe);
        String result = sb.toString();
    }

    @Test(sort = 32)
    private void strBufferAppendFinalIf() {
        StringBuffer sb = new StringBuffer(fa).append(fb);

        for(int i = 0 ; i < loop/10 ; i++) {
            if (index == 3) {
                sb.append(fc);
            }
        }

        sb.append(fd).append(fe);
        String result = sb.toString();
    }

    public static void main(String[] args) {
        new StringAppend().strAddTest();
    }

}
